package io.github.yotta.export.web.iface;

import io.github.yotta.common.api.model.ApiPageRequest;
import io.github.yotta.common.api.model.Paging;
import io.github.yotta.common.utils.param.MoreObject;
import io.github.yotta.export.core.enums.ExcelType;
import io.github.yotta.export.core.model.ExecuteContext;
import io.github.yotta.export.core.model.XlsxDataExportResult;
import io.github.yotta.export.web.anno.ExportExcelData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ResolvableType;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author yotta
 * @date 2025/4/27
 */
@Slf4j
public class MethodSpringExcelDataExporter<M, R extends ApiPageRequest> implements SpringExcelDataExporter<M, R> {

    private final ExportExcelData excelDataExporterAnno;
    private final Object target;
    private final Method method;
    private final ExportParamConvert<R> paramConvert;
    ;


    public MethodSpringExcelDataExporter(ExportExcelData excelDataExporterAnno,
                                         Object target,
                                         Method method,
                                         ExportParamConvert<R> paramConvert) {
        this.excelDataExporterAnno = excelDataExporterAnno;
        this.target = target;
        this.method = method;
        this.paramConvert = paramConvert;

    }

    @Override
    public ExportParamConvert<R> paramConvert() {
        return paramConvert;
    }


    @Override
    public ExcelType excelType(ApiPageRequest exportParam, ExecuteContext context) {
        return excelDataExporterAnno.fileType();
    }

    @Override
    public String sheetName(ApiPageRequest exportParam, ExecuteContext context) {
        return excelDataExporterAnno.sheetName();
    }

    @Override
    @SuppressWarnings("unchecked")
    public Class<M> modelClass() {
        // 获取返回值中paging的泛型类型
        return (Class<M>) ResolvableType.forMethodReturnType(method).resolveGeneric(0);
    }


    @Override
    @SuppressWarnings("unchecked")
    public Paging<M> exportData(R exportParam, ExecuteContext context) {
        try {
            return (Paging<M>) method.invoke(target, exportParam);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public String exportFileName(ApiPageRequest exportParam, ExecuteContext context) {
        return MoreObject.firstNoneEmpty(excelDataExporterAnno.fileName(), excelDataExporterAnno.name());
    }

    public void exportFinished(XlsxDataExportResult result, ExecuteContext context) {
        log.info("{} export file location => {}", excelDataExporterAnno.name(), result.getExportFilePath());
    }

}
